﻿Imports System.Runtime.Serialization

<DataContract()> _
Public Class LiveProgram
    Implements ICloneable

    Private _Id As Integer
    Public Property Id() As Integer
        Get
            Return _Id
        End Get
        Set(ByVal value As Integer)
            _Id = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.Id
        End Set
    End Property

    Private _Title As String
    Public Property Title() As String
        Get
            Return _Title
        End Get
        Set(ByVal value As String)
            _Title = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.Title
        End Set
    End Property

    Private _Description As String
    Public Property Description() As String
        Get
            Return _Description
        End Get
        Set(ByVal value As String)
            _Description = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.Description
        End Set
    End Property

    Private _CasterName As String
    Public Property CasterName() As String
        Get
            Return _CasterName
        End Get
        Set(ByVal value As String)
            _CasterName = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.CasterName
        End Set
    End Property

    Private _CasterId As Integer
    Public Property CasterId() As Integer
        Get
            Return _CasterId
        End Get
        Set(ByVal value As Integer)
            _CasterId = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.CasterId
        End Set
    End Property

    Private _VisitorCount As Integer
    Public Property VisitorCount() As Integer
        Get
            Return _VisitorCount
        End Get
        Set(ByVal value As Integer)
            _VisitorCount = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.VisitorCount
        End Set
    End Property

    Private _CommentCount As Integer
    Public Property CommentCount() As Integer
        Get
            Return _CommentCount
        End Get
        Set(ByVal value As Integer)
            _CommentCount = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.CommentCount
        End Set
    End Property

    Private _StartDateTime As DateTime
    Public Property StartDateTime() As DateTime
        Get
            Return _StartDateTime
        End Get
        Set(ByVal value As DateTime)
            _StartDateTime = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.StartDateTime
        End Set
    End Property

    Private _OfficialTag As String
    Public Property OfficialTag() As String
        Get
            Return _OfficialTag
        End Get
        Set(ByVal value As String)
            _OfficialTag = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.OfficialTag
        End Set
    End Property

    Private _AvailableProperties As LiveProgramProperties
    Public ReadOnly Property AvailableProperties As LiveProgramProperties
        Get
            Return _AvailableProperties
        End Get
    End Property

#Region "Kinds"
    Private _Kinds As LiveProgramKinds
    ''' <summary>
    ''' 放送の属性
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property Kinds() As LiveProgramKinds
        Get
            Return _Kinds
        End Get
        Set(ByVal value As LiveProgramKinds)
            _Kinds = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.Kinds
        End Set
    End Property

    ''' <summary>
    ''' 限定放送
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Xml.Serialization.XmlIgnore()>
    Public Property IsMemberOnly() As Boolean
        Get
            Return (_Kinds And LiveProgramKinds.MemberOnly) = LiveProgramKinds.MemberOnly
        End Get
        Set(ByVal value As Boolean)
            If value Then
                _Kinds = _Kinds Or LiveProgramKinds.MemberOnly
            Else
                _Kinds = _Kinds And Not LiveProgramKinds.MemberOnly
            End If
        End Set
    End Property

    ''' <summary>
    ''' 顔出し
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Xml.Serialization.XmlIgnore()>
    Public Property IsFace() As Boolean
        Get
            Return (_Kinds And LiveProgramKinds.Face) = LiveProgramKinds.Face
        End Get
        Set(ByVal value As Boolean)
            If value Then
                _Kinds = _Kinds Or LiveProgramKinds.Face
            Else
                _Kinds = _Kinds And Not LiveProgramKinds.Face
            End If
        End Set
    End Property

    ''' <summary>
    ''' 凸待ち
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Xml.Serialization.XmlIgnore()>
    Public Property IsTotsu() As Boolean
        Get
            Return (_Kinds And LiveProgramKinds.Totsu) = LiveProgramKinds.Totsu
        End Get
        Set(ByVal value As Boolean)
            If value Then
                _Kinds = _Kinds Or LiveProgramKinds.Totsu
            Else
                _Kinds = _Kinds And Not LiveProgramKinds.Totsu
            End If
        End Set
    End Property

    ''' <summary>
    ''' 予約放送
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    <Xml.Serialization.XmlIgnore()>
    Public Property IsReserved() As Boolean
        Get
            Return (_Kinds And LiveProgramKinds.Reserved) = LiveProgramKinds.Reserved
        End Get
        Set(ByVal value As Boolean)
            If value Then
                _Kinds = _Kinds Or LiveProgramKinds.Reserved
            Else
                _Kinds = _Kinds And Not LiveProgramKinds.Reserved
            End If
        End Set
    End Property

#End Region

    Private _IsOnAir As Boolean
    ''' <summary>
    ''' 放送中であるか
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property IsOnAir() As Boolean
        Get
            Return _IsOnAir
        End Get
        Set(ByVal value As Boolean)
            _IsOnAir = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.IsOnAir
        End Set
    End Property

    Private _CrawlingDateTime As DateTime
    ''' <summary>
    ''' 情報取得日時
    ''' </summary>
    ''' <value></value>
    ''' <returns></returns>
    ''' <remarks></remarks>
    Public Property CrawlingDateTime() As DateTime
        Get
            Return _CrawlingDateTime
        End Get
        Set(ByVal value As DateTime)
            _CrawlingDateTime = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.CrawlingDateTime
        End Set
    End Property

    Private _IsAlerted As Boolean
    Public Property IsAlerted() As Boolean
        Get
            Return _IsAlerted
        End Get
        Set(ByVal value As Boolean)
            _IsAlerted = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.IsAlerted
        End Set
    End Property

    'Private _AlertReason As New List(Of Guid)
    'Public Property AlertReason() As  IList(of 
    'Get
    'Return _AlertReason
    'End Get
    'Set(ByVal value As AlertReason)
    '_AlertReason = value
    'End Set
    'End Property

    Private _Uri As Uri
    Public Property Uri() As Uri
        Get
            If _Uri Is Nothing Then
                Return New Uri(String.Format(LiveProgramsUriFormat, Me.Id))
            End If
            Return _Uri
        End Get
        Set(ByVal value As Uri)
            _Uri = value
            _AvailableProperties = _AvailableProperties Or LiveProgramProperties.Uri
        End Set
    End Property

    Public Shared ReadOnly Property LiveProgramsUriFormat() As String
        Get
            Return "http://live.nicovideo.jp/watch/lv{0}"
        End Get
    End Property

    Private _Station As New Station
    Public ReadOnly Property Station As Station
        Get
            Return _Station
        End Get
    End Property

#Region "Normalization"


    Private NormalizedTitleReference As WeakReference
    Public ReadOnly Property NormalizedTitle() As String
        Get
            Dim target = NormalizedTitleReference
            If target IsNot Nothing Then
                Return Convert.ToString(target)
            End If

            If Me.Title = "" Then
                Return Me.Title
            End If

            Dim text = (New NormalizedText(Me.Title)).ToString
            NormalizedTitleReference = New WeakReference(text)
            Return text
        End Get
    End Property

    Private NormalizedDescriptionReference As WeakReference
    Public ReadOnly Property NormalizedDescription() As String
        Get
            Dim target = NormalizedDescriptionReference
            If target IsNot Nothing Then
                Return Convert.ToString(target)
            End If

            If Me.Description = "" Then
                Return Me.Description
            End If

            Dim text = (New NormalizedText(Me.Description)).ToString
            NormalizedDescriptionReference = New WeakReference(text)
            Return text
        End Get
    End Property

    Private NormalizedCasterNameReference As WeakReference
    Public ReadOnly Property NormalizedCasterName() As String
        Get
            Dim target = NormalizedCasterNameReference
            If target IsNot Nothing Then
                Return Convert.ToString(target)
            End If

            If Me.CasterName = "" Then
                Return Me.CasterName
            End If

            Dim text = (New NormalizedText(Me.CasterName)).ToString
            NormalizedCasterNameReference = New WeakReference(text)
            Return text
        End Get
    End Property

#End Region

    Public Function Clone() As Object Implements System.ICloneable.Clone

        Dim p = New LiveProgram

        ' 
        If (Me.AvailableProperties And LiveProgramProperties.Id) = LiveProgramProperties.Id Then
            p.Id = Me.Id
        End If
        If (Me.AvailableProperties And LiveProgramProperties.Title) = LiveProgramProperties.Title Then
            p.Title = Me.Title
        End If
        If (Me.AvailableProperties And LiveProgramProperties.Description) = LiveProgramProperties.Description Then
            p.Description = Me.Description
        End If
        If (Me.AvailableProperties And LiveProgramProperties.CasterName) = LiveProgramProperties.CasterName Then
            p.CasterName = Me.CasterName
        End If
        If (Me.AvailableProperties And LiveProgramProperties.CasterId) = LiveProgramProperties.CasterId Then
            p.CasterId = Me.CasterId
        End If
        If (Me.AvailableProperties And LiveProgramProperties.VisitorCount) = LiveProgramProperties.VisitorCount Then
            p.VisitorCount = Me.VisitorCount
        End If
        If (Me.AvailableProperties And LiveProgramProperties.CommentCount) = LiveProgramProperties.CommentCount Then
            p.CommentCount = Me.CommentCount
        End If
        If (Me.AvailableProperties And LiveProgramProperties.StartDateTime) = LiveProgramProperties.StartDateTime Then
            p.StartDateTime = Me.StartDateTime
        End If
        If (Me.AvailableProperties And LiveProgramProperties.OfficialTag) = LiveProgramProperties.OfficialTag Then
            p.OfficialTag = Me.OfficialTag
        End If
        If (Me.AvailableProperties And LiveProgramProperties.Kinds) = LiveProgramProperties.Kinds Then
            p.Kinds = Me.Kinds
        End If
        If (Me.AvailableProperties And LiveProgramProperties.IsOnAir) = LiveProgramProperties.IsOnAir Then
            p.IsOnAir = Me.IsOnAir
        End If
        If (Me.AvailableProperties And LiveProgramProperties.IsAlerted) = LiveProgramProperties.IsAlerted Then
            p.IsAlerted = Me.IsAlerted
        End If
        If (Me.AvailableProperties And LiveProgramProperties.CrawlingDateTime) = LiveProgramProperties.CrawlingDateTime Then
            p.CrawlingDateTime = Me.CrawlingDateTime
        End If
        If (Me.AvailableProperties And LiveProgramProperties.Uri) = LiveProgramProperties.Uri Then
            p.Uri = Me.Uri
        End If


        ' Station
        p.Station.Id = Me.Station.Id
        p.Station.IsFavorite = Me.Station.IsFavorite
        p.Station.Name = Me.Station.Name
        p.Station.IconUri = Me.Station.IconUri
        p.Station.AlertGroupId = Me.Station.AlertGroupId
        ' TODO all copy

        Return p

    End Function
End Class
